void restore_fpu(struct exec_domain *tsk)
{
+ /*
+ * FXRSTOR can fault if passed a corrupted data block. We handle this
+ * possibility, which may occur if the block was passed to us by control
+ * tools, by silently clearing the block.
+ */
if ( cpu_has_fxsr )
__asm__ __volatile__ (
- "fxrstor %0"
- : : "m" (tsk->arch.guest_context.fpu_ctxt) );
+ "1: fxrstor %0 \n"
+ ".section .fixup,\"ax\" \n"
+ "2: push %%"__OP"ax \n"
+ " push %%"__OP"cx \n"
+ " push %%"__OP"di \n"
+ " lea %0,%%"__OP"di \n"
+ " mov %1,%%ecx \n"
+ " xor %%eax,%%eax \n"
+ " rep ; stosl \n"
+ " pop %%"__OP"di \n"
+ " pop %%"__OP"cx \n"
+ " pop %%"__OP"ax \n"
+ " jmp 1b \n"
+ ".previous \n"
+ ".section __ex_table,\"a\"\n"
+ " "__FIXUP_ALIGN" \n"
+ " "__FIXUP_WORD" 1b,2b \n"
+ ".previous \n"
+ :
+ : "m" (tsk->arch.guest_context.fpu_ctxt),
+ "i" (sizeof(tsk->arch.guest_context.fpu_ctxt)/4) );
else
__asm__ __volatile__ (
"frstor %0"